package com.jspgou.cms.action.admin.main;

import static com.jspgou.common.page.SimplePage.cpn;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.jspgou.cms.entity.Order;
import com.jspgou.cms.entity.OrderItem;
import com.jspgou.cms.entity.Payment;
import com.jspgou.cms.entity.Product;
import com.jspgou.cms.entity.ProductFashion;
import com.jspgou.cms.entity.Shipping;
import com.jspgou.cms.entity.ShopAdmin;
import com.jspgou.cms.entity.ShopMember;
import com.jspgou.cms.entity.Order.OrderStatus;
import com.jspgou.cms.entity.ShopScore;
import com.jspgou.cms.manager.OrderMng;
import com.jspgou.cms.manager.OrderReturnMng;
import com.jspgou.cms.manager.PaymentMng;
import com.jspgou.cms.manager.ProductFashionMng;
import com.jspgou.cms.manager.ProductMng;
import com.jspgou.cms.manager.ShippingMng;
import com.jspgou.cms.manager.ShopMemberMng;
import com.jspgou.cms.manager.ShopScoreMng;
import com.jspgou.cms.web.CmsUtils;
import com.jspgou.cms.web.threadvariable.AdminThread;
import com.jspgou.common.page.Pagination;
import com.jspgou.common.web.CookieUtils;
import com.jspgou.common.web.RequestUtils;
import com.jspgou.common.web.ResponseUtils;
import com.jspgou.core.entity.Website;
import com.jspgou.core.manager.LogMng;
import com.jspgou.core.web.SiteUtils;
import com.jspgou.core.web.WebErrors;

@Controller
public class OrderAct {
	private static final Logger log = LoggerFactory.getLogger(OrderAct.class);
	public static final String ALL = "all";
	public static final String PENDING = "pending";
	public static final String PROSESSING = "processing";
	public static final String DELIVERED = "delivered";
	public static final String COMPLETE = "complete";
	public static final String[] TYPES = { ALL, PENDING, PROSESSING, DELIVERED,
			COMPLETE };

	@RequestMapping("/order/v_list.do")
	public String list(Integer status,Boolean isRefunded, Long source,Long paymentId, Long shoppingId,String code, 
			Date startTime,Date endTime,Double startOrderTotal,Double endOrderTotal,
			Integer paymentStatus,Integer shippingStatus,
			Integer pageNo, HttpServletRequest request,
			ModelMap model) {
		Website web = SiteUtils.getWeb(request);
		String productName = RequestUtils.getQueryParam(request, "productName");
		String userName = RequestUtils.getQueryParam(request, "userName");
		productName = StringUtils.trim(productName);
		userName = StringUtils.trim(userName);
		Pagination pagination = manager.getPage(web.getId(), null,null,status,isRefunded,code,source,productName,userName,
				paymentId,shoppingId,paymentStatus,shippingStatus,null, startTime,endTime,startOrderTotal,endOrderTotal,
				cpn(pageNo), CookieUtils.getPageSize(request));
		model.addAttribute("pagination", pagination);
		
		List<Shipping> shippingList = shippingMng.getList(web.getId(),null, null,true);
		List<Payment> paymentList = paymentMng.getList(web.getId(), true);
		model.addAttribute("source", source);
		model.addAttribute("productName", productName);
		model.addAttribute("paymentList", paymentList);
		model.addAttribute("code",code);
		model.addAttribute("shippingList", shippingList);
		model.addAttribute("statusList", OrderStatus.values());		
		model.addAttribute("status", status);
		model.addAttribute("paymentStatus", paymentStatus);
		model.addAttribute("shippingStatus", shippingStatus);
		//是否是预售订单
		model.addAttribute("isRefunded", isRefunded);
		model.addAttribute("shoppingId", shoppingId);
		//下单时间（开始）
		model.addAttribute("startTime", startTime);
		//下单时间（结束）
		model.addAttribute("endTime", endTime);
		//收货人
		model.addAttribute("userName", userName);
		//支付方式
		model.addAttribute("paymentId", paymentId);
		//订单金额（从）
		model.addAttribute("startOrderTotal",startOrderTotal);
		//订单金额（到）
		model.addAttribute("endOrderTotal", endOrderTotal);
		return "order/list";
	}
	
	//发货方法按钮
	@RequestMapping("/order/v_sendGoods.do")
	public String shipmentses(Long id,HttpServletRequest request,ModelMap model){
		WebErrors errors=validateEdit(id,request);
		if(errors.hasErrors()){
			return errors.showErrorPage(model);
		}
		Order order=manager.findById(id);
		model.addAttribute("order", order);
		return "order/sendGoods";
	}
	
	@RequestMapping("/order/v_view.do")
	public String view(Long id,HttpServletRequest request,ModelMap model){
		Website web=SiteUtils.getWeb(request);
		WebErrors errors=validateEdit(id,request);
		if(errors.hasErrors()){
			return errors.showErrorPage(model);
		}
		model.addAttribute("order", manager.findById(id));
		return "order/view";
	}
	
	//确认方法按钮
	@RequestMapping("/order/o_affirm.do")
	public String affirm(Long id,HttpServletRequest request,ModelMap model){
		Website web=SiteUtils.getWeb(request);
		WebErrors errors=validateEdit(id,request);
		if(errors.hasErrors()){
			return errors.showErrorPage(model);
		}
		Order order=manager.findById(id);
		if(order.getStatus()==1){
			order.setStatus(2);
			manager.updateByUpdater(order);
		}
		model.addAttribute("order", order);
		return "order/view";
	}
	
	//完成收货按钮
	@RequestMapping("/order/o_accomplish.do")
	public String accomplist(Long id,HttpServletRequest request,ModelMap model){
		WebErrors errors=validateEdit(id, request);
		if(errors.hasErrors()){
			return errors.showErrorPage(model);
		}
		Order order=manager.findById(id);
		if(order.getShippingStatus()==2&&order.getStatus()==2&&order.getPaymentStatus()==2){
			//更改订单的状态
			order.setStatus(4);
			//会员冻结的积分
			ShopMember member=order.getMember();
			//冻结的积分清除掉
			member.setFreezeScore(member.getFreezeScore()-order.getScore());
			//会员的积分相应的增加
			member.setScore(member.getScore()+order.getScore());
			shopMemberMng.update(member);
			List<ShopScore> list=shopScoreMng.getlist(order.getCode());
			for(ShopScore s:list){
				s.setStatus(true);
				shopScoreMng.update(s);
			}
			manager.updateByUpdater(order);
		}
		model.addAttribute("order", order);
		return "order/view";
	}
	
	/**
	 * 涉及到三张表，订单表order，订单项OrderItem,一个订单可能会有多个商品，即一个订单会有多个订单项
	 * product商品表，productFashion商品款式，一个商品可能会有多个款式
	 * 取消了之后相应的库存会增加
	 * 获得的积分会相应的减少
	 * @param id订单id
	 * @param request
	 * @param model
	 * @return
	 */
	//取消方法按钮
	@RequestMapping("/order/o_abolish.do")
	public String abolish(Long id,HttpServletRequest request,ModelMap model){
		Website web=SiteUtils.getWeb(request);
		WebErrors errors=validateEdit(id,request);
		if(errors.hasErrors()){
			return errors.showErrorPage(model);
		}
		Order order=manager.findById(id);
		if(order.getStatus()!=4&&order.getShippingStatus()!=2&&order.getPaymentStatus()!=2){
			order.setStatus(3);
			//处理库存,OrderItem订单项
			for(OrderItem item:order.getItems()){
				//找出哪些商品
				Product product=item.getProduct();
				//如果商品款式外键不为空
				if(item.getProductFash()!=null){
					ProductFashion fashion=item.getProductFash();
					//款式库存增加
					fashion.setStockCount(fashion.getStockCount()+item.getCount());
					//商品库存增加
					product.setStockCount(product.getStockCount()+item.getCount());
					productFashionMng.update(fashion);
				}else{
					product.setStockCount(product.getStockCount()+item.getCount());
				}
				productMng.update(product);
			}
			//会员冻结的积分
			//获取会员
			ShopMember member=order.getMember();
			//把会员购买的商品获得的积分减掉
			member.setFreezeScore(member.getFreezeScore()-order.getScore());
			shopMemberMng.update(member);
			//积分明细类ShopScore
			List<ShopScore> list=shopScoreMng.getlist(order.getCode());
			for(ShopScore s:list){
				shopScoreMng.deleteById(s.getId());
			}
			manager.updateByUpdater(order);
		}
		model.addAttribute("order", order);
		return "order/view";
	}
	
	@RequestMapping("/order/v_edit.do")
	public String edit(Long id, HttpServletRequest request, ModelMap model) {
		Website web = SiteUtils.getWeb(request);
		WebErrors errors = validateEdit(id, request);
		if (errors.hasErrors()) {
			return errors.showErrorPage(model);
		}
		String uploadRoot=web.getUploadUrl();
		model.addAttribute("uploadRoot", uploadRoot);

		List<Shipping> shippingList = shippingMng.getList(web.getId(),null,null, true);
		List<Payment> paymentList = paymentMng.getList(web.getId(), true);
		model.addAttribute("order", manager.findById(id));
		model.addAttribute("paymentList", paymentList);
		model.addAttribute("shippingList", shippingList);
		model.addAttribute("statusList", OrderStatus.values());
		model.addAttribute("orderReturn", orderReturnMng.findByOrderId(id));
		return "order/edit";
	}
	
	/**
	 * 订单修改
	 * @param id
	 * @param status 
	 * @param type
	 * @param freight	运费
	 * @param comments	内容
	 * @param shippingId	配送对应的值
	 * @param itemId	订单项对应的值
	 * @param itemCount	每个商品的数量
	 * @param itemPrice	 每个商品的单价
	 * @param totalPrice	商品总价格（不包含运费）
	 * @param pageNo
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping("/order/o_update.do")
	public String update(Long id, Integer status,String type, Double freight,
			String comments,Long shippingId,Long[] itemId, Integer[] itemCount,
			Double[] itemPrice,Double totalPrice, Integer pageNo,
			HttpServletRequest request,HttpServletResponse response, ModelMap model) {
		WebErrors errors = validateUpdate(id, status, freight,shippingId,itemId,itemCount,itemPrice,request);
		if (errors.hasErrors()) {return errors.showErrorPage(model);}
		Order order = manager.findById(id);
		ShopMember member = order.getMember();
		Set<OrderItem> items = order.getItems();
		Set<OrderItem> newItems = new HashSet<OrderItem>();
	    Integer i;
	    for (OrderItem item : items) {
	         	i = findItem(itemId, item.getId());
		        if (i != null) {
		         	if (itemCount[i]<= 0) {continue;}
			         item.setSalePrice(itemPrice[i]);
			         item.setCount(itemCount[i]);
			         newItems.add(item);
		    }
	    }
	    //清除订单项
	    order.getItems().clear();
	    for (OrderItem item : newItems) {
	    	//加入修改后的订单项
	         order.addToItems(item);
	    }
	    Double total=freight+totalPrice;
	    order.setFreight(freight);
	    order.setProductPrice(totalPrice);
	    order.setTotal(total);
	    order.setComments(comments);
		order.setShipping(shippingMng.findById(shippingId));
		order.setLastModified(new Timestamp(System.currentTimeMillis()));
	    manager.updateByUpdater(order);
		log.info("update Order, id={}.", order.getId());
		logMng.operating(request, "更改订单", "id="+order.getId());
		return list(null,null,null,null,null,null,null,null,null,null,null,null, pageNo, request, model);
	}
	
//	@RequestMapping("/order/o_returnMoney.do")
//	public void returnMoney(Long id,HttpServletRequest request,
//			HttpServletResponse response, ModelMap model) {
//		Website web = SiteUtils.getWeb(request);
//	    OrderReturn orderReturn=orderReturnMng.findByOrderId(id);
//    	if(orderReturn.getReturnPayType().getId()==33){
//    		Payment pay=paymentMng.findById((long)3);
//	    	PrintWriter out = null;
//			try {
//				String aliURL = alipayReturn(pay,web,orderReturn, request, model);
//				response.setContentType("text/html;charset=UTF-8");
//				out = response.getWriter();
//				out.print(aliURL);
//			} catch (Exception e) {
//			}finally{
//				out.close();
//			}
//    	}
//	}
	
//	private String alipayReturn(Payment pay,Website web,OrderReturn orderReturn,
//			HttpServletRequest request,ModelMap model){
//		////////////////////////////////////请求参数//////////////////////////////////////
//		//必填参数//
//		Date date=new Date();
//		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
//		SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		String date1=sdf.format(date);
//		//退款批次号。格式为：退款日期（8位当天日期）+流水号（3～24位，不能接受“000”，但是可以接受英文字符）
////		String batch_no = request.getParameter("batch_no");
//		String batch_no = date1.concat(String.valueOf(orderReturn.getId()*100));
//		//退款请求时间
////		String refund_date = request.getParameter("refund_date");
//		String refund_date = sdf1.format(date);
//		//退款总笔数
////		String batch_num = request.getParameter("batch_num");
//		String batch_num =String.valueOf(1);
//		//单笔数据集
////		String detail_data =  new String(request.getParameter("detail_data").getBytes("ISO-8859-1"),"gbk");
//		String detail_data = orderReturn.getOrder().getId().toString()+"^"+1.00+"^"+orderReturn.getShopDictionary().getName();
//		//格式：第一笔交易#第二笔交易#第三笔交易
//	        //第N笔交易格式：交易退款信息
//	        //交易退款信息格式：原付款支付宝交易号^退款总金额^退款理由
//	        //注意：
//	        //1.detail_data中的退款笔数总和要等于参数batch_num的值
//	        //2.detail_data的值中不能有“^”、“|”、“#”、“$”等影响detail_data的格式的特殊字符
//	        //3.detail_data中退款总金额不能大于交易总金额
//	        //4.一笔交易可以多次退款，只需要遵守多次退款的总金额不超过该笔交易付款时金额。
//	        //5.不支持退分润功能
//		//选填参数（以下两个参数不能同时为空）
//		//卖家支付宝账号
////		String seller_email = request.getParameter("seller_email");
////		String seller_email = pay.getSellerEmail();
//		//卖家用户ID
////		String seller_user_id = request.getParameter("seller_user_id");
////		String seller_user_id = pay.getSellerKey();
//		//服务器页面跳转同步通知页面
//		String notify_url="http://"+web.getDomain()+"/cart/aliReturn.jspx";
//		//////////////////////////////////////////////////////////////////////////////////
//		//把请求参数打包成数组
//		Map<String, String> sParaTemp = new HashMap<String, String>();
////		sParaTemp.put("partner", pay.getPartner());
////		sParaTemp.put("seller_email", seller_email);
////		sParaTemp.put("seller_user_id", seller_user_id);
//        sParaTemp.put("batch_no", batch_no);
//        sParaTemp.put("refund_date", refund_date);
//        sParaTemp.put("batch_num", batch_num);
//        sParaTemp.put("detail_data", detail_data);
//        sParaTemp.put("notify_url", notify_url);
//		//构造函数，生成请求URL  
//		String sHtmlText=null;
//		try {
//			sHtmlText = AlipayService.refund_fastpay_by_platform_pwd(sParaTemp);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
////		out.println(sHtmlText);
//		return sHtmlText;
//	}
	
	//计算运费
	@RequestMapping(value = "/order/ajaxtotalDeliveryFee.do")
	public void ajaxtotalDeliveryFee(Long deliveryMethod,Double weight,
			HttpServletRequest request, HttpServletResponse response,
			ModelMap model) throws JSONException {
		ShopMember member=CmsUtils.getMember(request);
		JSONObject json=new JSONObject();
		if (member == null) {
			json.put("status", 0);
		}
		Shipping shipping=shippingMng.findById(deliveryMethod);
		//计算运费
		Double freight=shipping.calPrice(weight);
		json.put("status", 1);
		json.put("freight", freight);
		ResponseUtils.renderJson(response, json.toString());
	}
	
	
	private Integer findItem(Long[] itemIds, Long itemId) {
		for(int i=0;i<itemIds.length;i++){
			if (itemIds[i].equals(itemId)) {
				return i;
			}
		}
		return null;
	}

	@RequestMapping("/order/o_delete.do")
	public String delete(Long[] ids, String type, Integer pageNo,
			HttpServletRequest request, ModelMap model) {
		WebErrors errors = validateDelete(ids, request);
		if (errors.hasErrors()) {
			return errors.showErrorPage(model);
		}
		Order[] beans;
//		try{			
			beans= manager.deleteByIds(ids);
			for (Order bean : beans) {
				log.info("delete Order, id={}", bean.getId());
			}
//		}catch(Exception e){
//			errors.addErrorString(productMng.getTipFile("delete.orderReturn"));
//			return errors.showErrorPage(model);
//		}
		return list(null,null,null,null,null,null,null,null,null,null,null,null, pageNo, request, model);
	}

	private WebErrors validateEdit(Long id, HttpServletRequest request) {
		WebErrors errors = WebErrors.create(request);
		Website web = SiteUtils.getWeb(request);
		if (vldExist(id, web.getId(), errors)) {
			return errors;
		}
		return errors;
	}

	private WebErrors validateUpdate(Long id, Integer status,
			Double freight,Long shippingId,Long[] itemId,
			Integer[] itemCount, Double[] itemPrice,
			HttpServletRequest request) {
		WebErrors errors = WebErrors.create(request);
		Website web = SiteUtils.getWeb(request);
		if (vldExist(id, web.getId(), errors)) {
			return errors;
		}
		if (itemId == null || itemCount == null || itemPrice == null
				|| itemId.length == 0 || itemId.length != itemCount.length
				|| itemCount.length != itemPrice.length) {
			errors.addErrorString("order item invalid!");
			return errors;
		}
		return errors;
	}

	private WebErrors validateDelete(Long[] ids, HttpServletRequest request) {
		WebErrors errors = WebErrors.create(request);
		Website web = SiteUtils.getWeb(request);
		errors.ifEmpty(ids, "ids");
		for (Long id : ids) {
			vldExist(id, web.getId(), errors);
		}
		return errors;
	}

	private boolean vldExist(Long id, Long webId, WebErrors errors) {
		if (errors.ifNull(id, "id")) {
			return true;
		}
		Order entity = manager.findById(id);
		if (errors.ifNotExist(entity, Order.class, id)) {
			return true;
		}
		if (!entity.getWebsite().getId().equals(webId)) {
			errors.notInWeb(Order.class, id);
			return true;
		}
		return false;
	}

	@Autowired
	private ShippingMng shippingMng;
	@Autowired
	private PaymentMng paymentMng;
	@Autowired 
	private ProductMng productMng;
	@Autowired
	private OrderMng manager;
	@Autowired
	private OrderReturnMng orderReturnMng;
	@Autowired
	private ProductFashionMng productFashionMng;
	@Autowired
	private ShopMemberMng shopMemberMng;
	@Autowired
	private ShopScoreMng shopScoreMng;
	@Autowired
	private LogMng logMng;
}